<?php

namespace Plugins\IMApi\Service;

use Hyperf\Di\Annotation\Inject;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;

/**
 * 绑定服务
 */
class BindService
{
    #[Inject]
    private CacheInterface $cache;

    /**
     * 绑定用户fd
     *
     * @param string $userId
     * @param int $fd
     * @return void
     * @throws InvalidArgumentException
     */
    public function bindUserFd(string $userId, int $fd): void
    {
        $userFds = $this->getUserFd($userId);
        if (in_array($fd, $userFds)) {
            return;
        }
        $userFds[] = $fd;
        $this->cache->set("user_fd:{$userId}", $userFds);
        $this->cache->set("fd_user:{$fd}", $userId);
    }

    /**
     * 解绑用户fd
     *
     * @param string $userId
     * @return void
     * @throws InvalidArgumentException
     */
    public function unBindUserFd(string $userId): void
    {
        $fds = $this->cache->get("user_fd:{$userId}");
        $this->cache->delete("user_fd:{$userId}");
        $this->cache->deleteMultiple(array_map(fn($fd) => "fd_user:{$fd}", $fds));
    }

    /**
     * 获取用户fd
     *
     * @param string $userId
     * @return array
     * @throws InvalidArgumentException
     */
    public function getUserFd(string $userId): array
    {
        return $this->cache->get("user_fd:{$userId}", []);
    }

    /**
     * 获取fd用户
     *
     * @param int $fd
     * @return int
     * @throws InvalidArgumentException
     */
    public function getFdUser(int $fd): int
    {
        return (int)$this->cache->get("fd_user:{$fd}");
    }

    /**
     * 绑定用户房间
     *
     * @param string $userId
     * @param string $roomId
     * @return void
     * @throws InvalidArgumentException
     */
    public function bindUserRoom(string $userId, string $roomId): void
    {
        $roomUsers = $this->getRoomUsers($roomId);
        if (!in_array($userId, $roomUsers)) {
            $roomUsers[] = $userId;
            $this->cache->set("room_users:{$roomId}", $roomUsers);
        }
        $userRooms = $this->getUserRooms($userId);
        if (!in_array($roomId, $userRooms)) {
            $userRooms[] = $roomId;
            $this->cache->set("user_rooms:{$userId}", $userRooms);
        }
    }

    /**
     * 解绑用户房间
     *
     * @param string $userId
     * @param string $roomId
     * @return void
     * @throws InvalidArgumentException
     */
    public function unBindUserRoom(string $userId, string $roomId): void
    {
        $roomUsers = $this->getRoomUsers($roomId);

        if (in_array($userId, $roomUsers)) {
            $roomUsers = array_filter($roomUsers, function ($item) use ($userId) {
                return $item != $userId;
            });
            $this->cache->set("room_users:{$roomId}", $roomUsers);
        }
        $userRooms = $this->getUserRooms($userId);
        if (in_array($roomId, $userRooms)) {
            $userRooms = array_filter($userRooms, function ($item) use ($roomId) {
                return $item != $roomId;
            });
            $this->cache->set("user_rooms:{$userId}", $userRooms);
        }
    }

    /**
     * 获取用户房间
     *
     * @param string $userId
     * @return mixed
     * @throws InvalidArgumentException
     */
    public function getUserRooms(string $userId): mixed
    {
        return $this->cache->get("user_rooms:{$userId}", []);
    }

    /**
     * 获取房间用户
     *
     * @param string $roomId
     * @return array
     * @throws InvalidArgumentException
     */
    public function getRoomUsers(string $roomId): array
    {
        return $this->cache->get("room_users:{$roomId}", []);
    }
}